package ru.myrtle.jst.emitter.java;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Utility class for Java related code generation.
 */
class JavaUtil {

    private static final String NL_PATTERN = "([\\n][\\r]?|[\\r][\\n]?)";

    public static void escapeJavaString(String originalText, StringBuffer escapedText) {
        for (int i = 0; i < originalText.length(); i++) {
            char ch = originalText.charAt(i);

            switch (ch) {
                case '\b':
                    escapedText.append("\\b");
                    break;
                case '\f':
                    escapedText.append("\\f");
                    break;
                case '\t':
                    escapedText.append("\\t");
                    break;
                case '\r':
                    escapedText.append("\\r");
                    break;
                case '\n':
                    escapedText.append("\\n");
                    break;
                case '"':
                    escapedText.append("\\\"");
                    break;
                case '\\':
                    escapedText.append("\\\\");
                    break;
                default:
                    escapedText.append(ch);
            }
        }
    }

    /**
     * Return a Java string, including initial and final double quotes, and inserting
     * any required Java escape sequences.
     *
     * @param text the text to quote
     * @return the quoted Java string
     */
    public static String asJavaQuotedString(String text) {
        StringBuffer encoded = new StringBuffer(
                text.length() + 2
        );

        encoded.append('"');
        escapeJavaString(text, encoded);
        encoded.append('"');

        return encoded.toString();
    }

    /**
     * Return a Java String expression with + NL + in place of new line data
     */
    public static String asJavaQuoteStringWithNLRemoved(String text) {
        Matcher m = Pattern.compile(NL_PATTERN, Pattern.MULTILINE).matcher(text);

        int nextStringStart = 0;
        boolean nlFound = m.find();

        if (nlFound) {
            StringBuffer result = new StringBuffer(text.length());
            boolean firstExprComponent = true;
            for (; nlFound; nlFound = m.find()) {
                if (firstExprComponent) {
                    firstExprComponent = false;
                }
                else {
                    result.append(" + ");
                }
                if (m.start() > nextStringStart) {
                    result.append(
                            asJavaQuotedString(
                                    text.substring(
                                            nextStringStart, m.start()
                                    )
                            )
                    );
                    result.append(" + ");
                }
                result.append("NL");
                nextStringStart = m.end();
            }
            if (nextStringStart < text.length()) {
                if (!firstExprComponent) {
                    result.append(" + ");
                    result.append(
                            asJavaQuotedString(
                                    text.substring(nextStringStart)
                            )
                    );
                }
            }
            return result.toString();
        }
        else {
            return asJavaQuotedString(text);
        }
    }
}
